(function () {
	type IsAny<T> = 0 extends 1 & T ? true : false;
	type IsNever<T> = [T] extends [never] ? true : false;
	type Tmp1 = 1 & (0 | 1); // 1
	type Tmp2 = 1 & number; // 1
	type Tmp3 = 1 & 1; // 1
	//因为交叉类型就像短板效应一样，其最终计算的类型是由最短的那根木板，也就是最精确的那个类型决定的。这样看，无论如何 0 extends 1 都不会成立。
	type Tmp4 = 1 & any; // any // 如果交叉类型的其中一个成员是 any，那短板效应就失效了，此时最终类型必然是 any 。
	type Tmp5 = 1 & unknown; // 1 //而对于 unknown 并不能享受到这个待遇，因为它并不是“身化万千”的

	//因此，我们并不能用这个方式来写 IsUnknown。其实现过程要更复杂一些，我们需要过滤掉其他全部的类型来只剩下 unknown 。这里直接看实现：
	type IsUnknown<T> = IsNever<T> extends false
		? T extends unknown
			? unknown extends T
				? IsAny<T> extends false
					? true
					: false
				: false
			: false
		: false;
	//首先过滤掉 never 类型，然后对于 T extends unknown 和 unknown extends T，只有 any 和 unknown 类型能够同时符合（还记得我们在类型层级一节进行的尝试吗？），如果再过滤掉 any，那肯定就只剩下 unknown 类型啦。
	type test12 = any extends unknown ? 1 : 2; // 1
	type test13 = unknown extends any ? 1 : 2; // 1

	type IsUnknownRes1 = IsUnknown<string>;
	type IsUnknownRes2 = IsUnknown<unknown>;
	//这里的 IsUnknown 类型其实可以使用更简单的方式实现。利用 unknown extends T 时仅有 T 为 any 或 unknown 时成立这一点，我们可以直接将类型收窄到 any 与 unknown，然后在去掉 any 类型时，我们仍然可以利用上面的身化万千特性：
	type IsUnknown2<T> = unknown extends T ? (IsAny<T> extends true ? false : true) : false;
	type IsUnknownRes3 = IsUnknown2<unknown>;
})();
